package com.zhu.esyblog.Aop;

import com.alibaba.fastjson.JSON;
import com.zhu.esyblog.Utils.HttpContextUtils;
import com.zhu.esyblog.Utils.IPUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Component
@Aspect //切面 定义了通知和切点的关系
@Slf4j
public class LogAspect {
    @Pointcut("@annotation(com.zhu.esyblog.Aop.LogAnnotation)")  //定义切面
    public void pt(){

    }

    @Around("pt()")  //通知切点  环绕通知
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object proceed = joinPoint.proceed();
        //执行时常
       long time=System.currentTimeMillis()-beginTime;

       recordLog(joinPoint,time);
       return proceed;
    }

    private void recordLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature= (MethodSignature) joinPoint.getSignature();
        Method method=signature.getMethod();
        //获取请求操作的描述信息
        LogAnnotation logAnnotation=method.getAnnotation(LogAnnotation.class);
       log.info("==========================log start========================");
       log.info("module:{}",logAnnotation.module());
       log.info("operation:{}",logAnnotation.operator());
        //获取操作方法名
        String className=joinPoint.getTarget().getClass().getName();
        String methodName=signature.getName();
        log.info("request:{}",className+"."+methodName+"()");

        //获取请求参数
        Object[] args=joinPoint.getArgs();
        String params= JSON.toJSONString(args[0]);
       log.info("params:{}",params);

        //获取ip
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        log.info("ip{}:", IPUtils.getIpAddr(request));

        log.info("execute time:{}",time);
        log.info("==============================log end==========================");
    }
}
